## 11. 标准库简介 -- part 2
pass
'''专业编程所需要的更高级的模块。
很少用在小脚本中。
'''
### 11.1. 格式化输出
print('-------------------------------- reprlib -----------------------------------')
import  reprlib
r = reprlib.repr(set('supercalifragilisticexpialidocious'))
print(r)

print('--------------------------------- pprint ----------------------------------')
import pprint
t = [[[['black', 'cyan'], 'white', ['green', 'red']], [['magenta','yellow'], 'blue'] ] ]
pprint.pprint(t, width=30)

print('-----------------------------------textwrap--------------------------------')
import textwrap
doc = """The wrap() method is just like fill() except that it returns
a list of strings instead of one big string with newlines to separate
the wrapped lines."""
print(textwrap.fill(doc, 20))

'''loclae
模块处理与特定地域文化相关的数据格式。
'''

### 11.2. 模板

'''string 模块包含一个通用的 Template 类
具有适用于最终用户的简化语法
'''
print('-------------------------------- string.Template -----------------------------------')
from string import  Template
t = Template('${village}folk send $$10 to $cause.')
tt = t.substitute(village='Nottingham', cause='the ditch fund')
print(tt)


### 11.3. 使用二进制数据记录格式
'''struct  处理不定长度的二进制记录格式
parck()
unparck()
'''

### 11.4. 多线程
'''线程是一种对于非顺序依赖的多个任务进行解耦的技术
threading
'''
print('-------------------------------- threading -----------------------------------')


import threading, zipfile

class AsyncZip(threading.Thread):
    def __init__(self, infile, outfile):
        threading.Thread.__init__(self)
        self.infile = infile
        self.outfile = outfile

    def run(self):
        f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED)
        f.write(self.infile)
        f.close()
        print('Finished backgroud zip of: ', self.infile)

background = AsyncZip('mydata.txt', 'myarchive.zip')
background.start()
print('The main program continues to run in foreground.')
background.join()    # Wait for the background task to finish
print('Main program waited until background was done.')

'''queue
向该线程供应来自其他线程的请求
进行线程间通信和协调，更易于设计，更易读，更可靠
'''

### 11.5. 日志记录
'''logging
日志记录系统
日志消息被发送到文件或 sys.stderr

优先级选择不同的路由方式：DEBUG，INFO，WARNING，ERROR，和 CRITICAL。
debug, info 默认被压制
'''
import logging
logging.debug('Debugging information')
logging.info('Informational message')

logging.warning('Warning:config file %s not found', 'server.conf')
logging.error('Error occurred')
logging.critical('Critical error -- shuting down')

### 11.6. 弱引用

'''Python 会自动进行内存管理
（对大多数对象进行引用计数并使用 garbage collection 来清除循环引用）

weakref 
gc
'''

### 11.7. 用于操作列表的工具

'''array
array 模块提供了一种 array() 对象，它类似于列表，但只能存储类型一致的数据且存储密集更高。
'''

print('-------------------------------- array.array() -----------------------------------')
from array import array
a = array('H', [4000, 10, 700, 2000])
print(sum(a))
print(a[1:3])

'''collections
deque() 对象 , 它类似于列表，但从左端添加和弹出的速度较快，而在中间查找的速度较慢。 
此种对象适用于实现队列和广度优先树搜索
'''

print('-------------------------------- collections.deque() -----------------------------------')
from collections import deque
d = deque(['task1', 'task2', 'task3'])
d.append('task4')
print("Handling ", d.popleft())

'''bisect
具有操作有序列表的函数
'''

print('-------------------------------- bisect -----------------------------------')
import bisect
scores = [(100, 'perl'), (200, 'tcl'), (500, 'lua'), (600, 'python')]
bisect.insort(scores, (300,  'ruby'))
print(scores)

'''heapq
提供了基于常规列表来实现堆的函数
最小值的条目总是保持在位置零。
'''
print('-------------------------------- heapq -----------------------------------')
from heapq import  heapify, heappop, heappush
data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
heapify(data)               # rearrange the list into heap order
print(data)
heappush(data, -5)          # add a new entry
print(data)
[heappop(data) for i in range(3)]  # etch the three smallest entries
print(data)

### 11.8. 十进制浮点运算

'''decimal
提供 Decimal 数据类型

相比内置的 float 二进制浮点实现，该类特别适用于
* 财务应用和其他需要精确十进制表示的用途，
* 控制精度，
* 控制四舍五入以满足法律或监管要求，
* 跟踪有效小数位，或
* 用户期望结果与手工完成的计算相匹配的应用程序。

精确表示特性使得 Decimal 类能够执行对于二进制浮点数来说不适用的模运算和相等性检测:
decimal 模块提供了运算所需要的足够精度:
'''

print('-------------------------------- decimal -----------------------------------')
from decimal import  *
r =  round(Decimal('0.70') * Decimal('1.05'), 2)
print(r)                                    # 0.74
print(0.70 * 1.05)                          # 0.735

print( Decimal('1.0') % Decimal('.10'))     # 0.00
print(1.0 % 0.10)                           # 0.09999999999999995

getcontext().prec = 36
print(Decimal(1) / Decimal(7))              # 0.142857142857142857142857142857142857